#ifdef _WIN32
#include <i_dll.h>
#include <filesystem>
#include <windows.h>
#include <sstream>

namespace std_fs = std::filesystem;

namespace dll
{
	class CDllFileWin : public IDllFile
	{
	public:
		CDllFileWin() : m_module(NULL)
		{}

		~CDllFileWin()
		{
			Close();
		}

		bool LoadFile(const std::string& path)
		{
			auto u8_path = std_fs::u8path(path);
			auto wpath = u8_path.wstring();
			m_module = LoadLibrary(wpath.c_str());
			
			if (m_module == NULL)
			{
				_OnError();
				return false;
			}

			return true;
		}

		bool GetEntery(const char* name, void** fun_ptr)
		{
			if (m_module == NULL)
				return false;

			*fun_ptr = nullptr;
			*fun_ptr = GetProcAddress(m_module, name);
			if (*fun_ptr == nullptr)
			{
				_OnError();
				return false;
			}

			return true;
		}

		void Close()
		{
			if (m_module != NULL)
			{
				FreeLibrary(m_module);
				m_module = NULL;
			}
		}

		const std::string& LastError()
		{
			return m_err;
		}
	protected:
		void _OnError()
		{
			std::stringstream ss;
			ss << "errno : " << GetLastError();
			m_err = ss.str();
		}

		HMODULE m_module;
		std::string m_err;
	};

	MISC_DLL_EXPORT IDllFilePtr CreateDllFile() {
		return std::make_shared<CDllFileWin>();
	}
}

#endif